package com.superjson.showpro.controller;

import com.alibaba.fastjson.JSONObject;
import com.beantools.filters.BuilderFilters;
import com.beantools.util.poutil.FileUtil;
import com.superjson.showpro.controller.core.BaseContoller;
import com.superjson.showpro.entity.Attach;
import com.superjson.showpro.service.AttachService;
import com.superjson.showpro.shared.enums.FileTypeEnum;
import com.superjson.showpro.shared.exception.GeneralBizException;
import com.superjson.showpro.shared.result.Result;
import com.superjson.showpro.shared.result.ResultCodeEnum;
import com.superjson.showpro.shared.result.ResultUtil;
import com.superjson.showpro.shared.util.LogUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Date;
import java.util.Iterator;

import static com.beantools.entity.enums.DateFormatEnum.ISO_DATETIME_FORMAT_NONE;
import static com.beantools.util.FastDateFormat.formatByEnum;
import static com.beantools.util.ObjectUtil.isNotNull;
import static com.beantools.util.StringUtil.isNotBlank;
import static com.superjson.showpro.shared.result.ResultCodeEnum.FILE_UPLOAD_FALSE;
import static com.superjson.showpro.shared.util.CommonUtil.getTomcatRootPath;
import static com.superjson.showpro.shared.util.CommonUtil.ifNullThrow;

/**
 * Created By zby on 23:07 2019/5/21
 * 这是文件的控制层
 *
 * @author baoya
 * @since 1.1.0
 */
@RestController("attachController")
@RequestMapping("/attach")
public class AttachController extends BaseContoller {

    @Autowired
    private AttachService attachService;
    @Value("#{attachConf['fileUploadRootPath']}")
    private String fileUploadRootPath;

    /**
     * Created By zby on 13:18 2019/6/24
     * 获取单个文件
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public Result getAttach(@PathVariable Long id) {
        Attach attach = attachService.get(id).getResultData();
        ifNullThrow(attach, ResultCodeEnum.FILE_NOT_EXIST);
        String[] attachJson = {"id", "name"};
        JSONObject body = BuilderFilters.builderPropertyFilters().filerJson(attachJson, attach);
        return ResultUtil.buildSuccess(body);
    }


    /**
     * Created By zby on 16:23 2019/6/22
     * 上传
     */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public Result upload(HttpServletRequest request, String description, FileTypeEnum fileType) {
        //将当前上下文初始化给  CommonsMutipartResolver （多部分解析器）
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                request.getSession().getServletContext());
        if (multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            //获取multiRequest 中所有的文件名
            Iterator iter = multiRequest.getFileNames();
            while (iter.hasNext()) {
                //一次遍历所有文件
                MultipartFile file = multiRequest.getFile(iter.next().toString());
                if (isNotNull(file)) {
                    try {
                        String originalFilename = file.getOriginalFilename();
                        Date date = new Date(System.currentTimeMillis());
                        String name = originalFilename.contains(".jar") ? originalFilename : formatByEnum(date, ISO_DATETIME_FORMAT_NONE) + originalFilename;
                        String relativePath = getTomcatRootPath() + fileUploadRootPath + name;
                        file.transferTo(new File(relativePath));
                        Attach attach = attachService.saveAttach(file, originalFilename, date, name, relativePath, description, fileType).getResultData();
                        String[] attachJson = {"id", "relativePath", "name"};
                        JSONObject body = BuilderFilters.builderPropertyFilters().filerJson(attachJson, attach);
                        return ResultUtil.buildSuccess(body);
                    } catch (IOException e) {
                        throw new GeneralBizException(e.getMessage());
                    }
                }
            }
            return ResultUtil.buildSuccess();
        } else {
            throw new GeneralBizException(FILE_UPLOAD_FALSE);
        }
    }

    /**
     * Created By zby on 16:23 2019/6/22
     * 下载文件
     */
    @RequestMapping(value = "/download", method = RequestMethod.GET)
    public Result download(HttpServletResponse response, Long id, String fileName) {
        response.setContentType("text/html;charset=utf-8");
        String relativePath = null;
        if (isNotNull(id)) {
            Attach attach = attachService.get(id).getResultData();
            ifNullThrow(attach, ResultCodeEnum.FILE_NOT_EXIST);
            relativePath = attach.getRelativePath();
            fileName = attach.getName();
        }
        if (isNotBlank(fileName)) {
            relativePath = getTomcatRootPath() + fileUploadRootPath + fileName;
        }
        LogUtil.info(logger,"down load path is:"+relativePath);
        BufferedInputStream src = null;
        BufferedOutputStream desc = null;
        try {
            File file = new File(relativePath);
            response.setContentType("application/x-msdownload;");
            response.setHeader("Content-disposition", "attachment; filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1"));
            response.setHeader("Content-Length", String.valueOf(file.length()));
            response.setContentLength((int) file.length());
            src = new BufferedInputStream(new FileInputStream(file));
            desc = new BufferedOutputStream(response.getOutputStream());
            int size = 2048;
            byte[] buffer = new byte[size];
            int n = 0;
            //遍历，开始下载
            while ((n = src.read(buffer, 0, size)) > -1) {
                desc.write(buffer, 0, n);
            }
            desc.flush();   //不可少
            response.flushBuffer();//不可少
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            FileUtil.closeInputStream(src);
            FileUtil.closeOutputStream(desc);
        }
        return ResultUtil.buildSuccess();
    }
}
